/*
 @Name: tab插件
 @Author: ray
 @License: MIT
 */
; rayui.define(["layer"], function (exports, undef) {
    "use strict";

    var $ = rayui.$,
        $win = $(window),
        $doc = $(document),
        $body = $('body'),
        layer = rayui.layer,
        plugName = "tab",
        globalIndex = 1000,
        dataCache = {},
        dict = {},
        winBingResize,
        DealClass = function (options) {
            options.index = globalIndex;
            this.options = $.extend({}, DealClass.option, options);

            //初始化
            DealClass.utils.init.call(this);
            DealClass.utils.initHeight.call(this);
            DealClass.utils.event.call(this);
            return this;
        };

    DealClass.option = {
        fieldId: "id", //数据列
        fieldName: "name", //显示列
        fieldIcon: "icon", //图标
        fieldUrl: "url", //图标
        fieldContent: "content", //内容
        closeBtn: true, //是否包含删除按钮
        autoRefresh: false,//选中选项卡时自动刷新
        contextMenu: false,//右键菜单，true|false
        loading: true, //true|false
        minHeight: 100
    };

    DealClass.utils = {
        init: function () {
            var that = this,
                options = that.options;

            options.$main = $(options.elem);
            options.$tabtitle = options.$main.find('.rayui-tab-title');
            options.$tabcontent = options.$main.find('.rayui-tab-content');
            //没有ul标签的添加ul
            options.$tabtitle.find('>ul').length === 0 && options.$tabtitle.append("<ul></ul>");
            //添加关闭按钮
            options.$tabtitle.find('>ul>li').each(function (a) {
                var index = $(this).index(), rayid = new Date().getTime() + a;
                $(this).attr("ray-id", rayid);
                options.$tabcontent.find('.rayui-tab-item:eq(' + index + ')').attr("ray-id", rayid);
                if (options.closeBtn && $(this).attr("allow-close") !== "false")
                    $(this).append('<span class="tab-btnclose"><i class="ra ra-wrong"></i></span>');
            });
            //调整高度
        },
        initHeight: function () {
            var that = this,
                options = that.options,
                fullHeightGap;

            !options.heightSetting && (options.heightSetting = options.height);

            if (/^full-\d+$/.test(options.heightSetting)) {//full-差距值
                options.heightAuto = true;
                fullHeightGap = options.heightSetting.split('-')[1];
                options.height = $win.height() - fullHeightGap;
            } else if (/^top-\d+$/.test(options.heightSetting)) {//top-差距值
                options.heightAuto = true;
                fullHeightGap = options.$main.offset().top;
                fullHeightGap += parseInt(options.heightSetting.split('-')[1]);
                options.height = $win.height() - fullHeightGap;
            } else if (/^sel-[#|\.][\w]+-\d+$/.test(options.heightSetting)) { //sel-id序列-差距值
                options.heightAuto = true;
                fullHeightGap = options.$main.offset().top;
                var list = options.heightSetting.split('-');
                $("" + list[1]).each(function () {
                    fullHeightGap += $(this).outerHeight();
                });
                if (list.length === 3) fullHeightGap += parseInt(list[2]);
                options.height = $win.height() - fullHeightGap;
            }

            //最终高度不能小于最小高度
            if (options.height < options.minHeight) options.height = options.minHeight;
            //数据高度-title
            var tmpH = options.height - options.$tabtitle.outerHeight();
            options.$tabcontent.outerHeight(tmpH);//数据设置高度
        },
        event: function () {
            var that = this,
                options = that.options,
                $ultile = options.$tabtitle.find('ul');

            //标题li点击
            $ultile.on("click." + plugName, '>li', function () {
                if (dict.moved) return;
                if ($(this).hasClass('rayui-active')) return;
                var rayid = $(this).attr('ray-id');
                $(this).addClass('rayui-active').siblings("li").removeClass('rayui-active');
                var $content = options.$tabcontent.find('.rayui-tab-item[ray-id=' + rayid + ']');
                $content.addClass('rayui-active').siblings(".rayui-tab-item").removeClass('rayui-active');
                if (options.autoRefresh) {
                    var $iframe = $content.find('iframe');
                    $iframe.length > 0 && !$iframe.data("loading") && $iframe.attr("src", $iframe.attr("src"));
                }
            });

            //按钮关闭
            $ultile.on("click." + plugName, '>li>.tab-btnclose', function (e) {
                e.stopPropagation();
                var $li = $(this).closest('li'),
                    rayid = $li.attr('ray-id');
                that.del(rayid, true);
            });

            //标题li右键菜单
            if (options.contextMenu) {
                $ultile.on("contextmenu." + plugName, '>li', function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    $(".rayui-tab-contextmenu").remove();
                    var $li = $(this),
                        rayid = $(this).attr("ray-id"),
                        allowColse = $li.attr("allow-close") === "false";
                    var ul = '<ul>';
                    ul += '<li data-event="refresh" title="刷新"><i class="ra ra-refresh" aria-hidden="true"></i> 刷新</li>';
                    ul += '<li '; allowColse && (ul += 'class="rayui-disabled" ');
                    ul += 'data-event="closeCur" title="关闭当前"><i class="ra ra-wrong" aria-hidden="true"></i> 关闭当前</li>';
                    ul += '<li data-event="closeOther" title="关闭其他"><i class="ra ra-close" aria-hidden="true"></i> 关闭其他</li>';
                    ul += '<li data-event="closeAll" title="关闭全部"><i class="ra ra-close" aria-hidden="true"></i> 全部关闭</li>';
                    ul += '</ul>';
                    var $div = $('<div class="rayui-tab-contextmenu">').html(ul);
                    $body.append($div);
                    var w = $div.outerWidth(),
                        cw = $win.width(),
                        x = e.pageX + w > cw ? cw - w : e.pageX;
                    $div.css({
                        top: e.pageY,
                        left: x
                    });
                    //右键菜单点击
                    $div.on("click", 'li:not(.rayui-disabled)', function () {
                        var event = $(this).data("event"), $content = options.$tabcontent.find('.rayui-tab-item[ray-id=' + rayid + ']');
                        switch (event) {
                            case "refresh":
                                var $iframe = $content.find("iframe");
                                if ($iframe.length > 0) $iframe[0].src = $iframe[0].src;
                                break;
                            case "closeCur":
                                that.del(rayid, true);
                                break;
                            case "closeOther":
                                options.$tabtitle.find('>ul>li').not($li).each(function () {
                                    if ($(this).attr("allow-close") !== "false")
                                        that.del($(this).attr("ray-id"));
                                });
                                that.swich(rayid);
                                break;
                            case "closeAll":
                                options.$tabtitle.find('>ul>li').each(function () {
                                    if ($(this).attr("allow-close") !== "false")
                                        that.del($(this).attr("ray-id"));
                                });
                                that.swich(options.$tabtitle.find('>ul>li:first').attr('ray-id'));
                                break;
                        }
                    });
                });
            }

            //拖动标题
            $ultile.on("mousedown." + plugName, function (e) {
                $(".rayui-tab-contextmenu").remove();
                dict.flag = true;
                dict.elem = $ultile;
                dict.boxW = options.$tabtitle.width();
                dict.liW = 0;
                $ultile.find("li").each(function () {
                    dict.liW += $(this).outerWidth();
                });
                dict.min = dict.boxW - dict.liW;
                dict.X = e.clientX;
                dict.left = parseFloat($ultile.css("left").replace("px", ""));
            });

            //绑定自适应
            options.heightAuto && !winBingResize && (winBingResize = true) &&
                $win.resize(function () {
                    for (var key in dataCache) {
                        DealClass.utils.initHeight.call(dataCache[key]);
                    }
                });

        }
    }

    DealClass.prototype = {
        add: function (data, index) {
            var that = this, options = that.options;
            data[options.fieldId] = data[options.fieldId] || new Date().getTime();

            //判断id是否存在tab
            if (options.$tabtitle.find('li[ray-id=' + data[options.fieldId] + ']').length > 0)
                return that.swich(data[options.fieldId]);

            var li = [], $li = options.$tabtitle.find("li[ray-id=" + data[options.fieldId] + "]");
            if ($li.length > 0) {
                $li.click();
                return that;
            }

            //添加tab
            li.push('<li ray-id="' + data[options.fieldId] + '"');
            data.allowClose === false && li.push(' allow-close="false"');
            li.push('>');
            var icon = data[options.fieldIcon];
            if (typeof icon === "string") {
                if (data[options.fieldIcon].indexOf('fa-') === 0) {
                    li.push('<i class="fa ' + icon + '" aria-hidden="true"></i>');
                } else if (icon.indexOf('ra-') === 0) {
                    li.push('<i class="ra ' + icon + '" aria-hidden="true"></i>');
                } else {
                    li.push('<img src="' + icon + '" alt=""/>');
                }
            }
            li.push('<span>' + (data[options.fieldName] || '标题') + '</span>');
            if (options.closeBtn && data.allowClose !== false)
                li.push('<span class="tab-btnclose"><i class="ra ra-wrong"></i></span>');
            li.push('</li>');

            //添加content
            var content = [
                '<div class="rayui-tab-item" ray-id="' + data[options.fieldId] + '">',
                data[options.fieldUrl] ? '<iframe src="' + data[options.fieldUrl] + '">' : data[options.fieldContent].replace(/[<>&"]/g, function (c) { return { '<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;' }[c]; }),
                '</div>'
            ], $content = $(content.join(''));

            var $to = options.$tabtitle.find('>ul>li:eq(' + index + ')');
            if ($to.length > 0) {
                $to.before(li.join(''));
                options.$tabcontent.find('.rayui-tab-item:eq(' + index + ')').before($content);
            } else {
                options.$tabtitle.find('>ul').append(li.join(''));
                options.$tabcontent.append($content);
            }
            //iframe的加载等待
            if (options.loading && data[options.fieldUrl]) {
                var waitIndex = typeof options.showLoadingFunc === "function" ?
                    options.showLoadingFunc()
                    : layer.loading({
                        container: options.$tabcontent,
                        offset: 5
                    }), $iframe = $content.find("iframe");
                $iframe.data("loading", true).on('load', function () {
                    typeof options.hideLoadingFunc === "function"
                        ? options.hideLoadingFunc(waitIndex)
                        : layer.close(waitIndex);
                    $iframe.data("loading", false);
                });
            }
            //选中
            return that.swich(data[options.fieldId]);
        },
        del: function (id, toid) {
            var that = this, options = that.options;
            if (toid === true) {
                var $li = options.$tabtitle.find('li[ray-id=' + id + ']');
                if ($li.hasClass("rayui-active")) {
                    var $to = $li.next();
                    $to.length === 0 && ($to = $li.prev());
                    toid = $to.attr('ray-id');
                }
            }

            options.$tabtitle.find('li[ray-id=' + id + ']').remove();
            options.$tabcontent.find('.rayui-tab-item[ray-id=' + id + ']').remove();
            return that.swich(toid);
        },
        swich: function (id) {
            var that = this;
            if (id === undef) return that;
            var options = that.options;
            options.$tabtitle.find('li[ray-id=' + id + ']').click();
            return that.moveToCurr();
        },
        moveToCurr: function () {
            var that = this, options = that.options,
                $titlebox = options.$tabtitle,
                boxwidth = $titlebox.width(),
                $ul = $titlebox.find('>ul');

            var liWidth = 0, linextWidth = 0; var isNext = false;
            $.each($ul.find(">li"), function () {
                var ww = $(this)[0].offsetWidth;
                liWidth += ww;
                if (isNext)
                    linextWidth += ww;
                if ($(this).hasClass("rayui-active")) {
                    isNext = true;
                }
            });
            if (boxwidth >= liWidth) {
                $ul.css("left", "0");
                return that;
            }
            var halfUlW = boxwidth / 2;
            if (linextWidth <= halfUlW) {
                $ul.css("left", boxwidth - liWidth);
                return that;
            }

            var obj = $ul.find('li.rayui-active');
            var left = obj.position().left + (obj[0].offsetWidth / 2);
            var offsetLeft = left - halfUlW;
            if (offsetLeft < 0) offsetLeft = 0;
            $ul.css("left", -offsetLeft);
            return that;
        }
    }

    $doc.on('click', function () {
        $(".rayui-tab-contextmenu").remove();
    });

    //拖拽中
    $doc.on('mousemove.' + plugName, function (e) {
        e.preventDefault();
        if (!dict.flag) return;
        var moveX = e.clientX - dict.X;
        if (Math.abs(moveX) < 5) return;
        var left = dict.left + moveX;
        if (left < dict.min) left = dict.min;
        if (left > 0) left = 0;
        dict.moved = dict.left !== left;
        dict.elem.css("left", left + "px");
    }).on('mouseup.' + plugName, function () {
        if (dict.flag) {
            dict.flag = false;
            setTimeout(function () { dict.moved = false; }, 10);
        }
    });

    var handler = {
        options: DealClass.option,
        render: function (options) {
            (typeof options === "string" || options instanceof jQuery) && (options = { elem: options });
            if ($(options.elem).length === 0) return "DOM对象不存在";
            var classObj = new DealClass(options);
            dataCache[globalIndex++] = classObj;
            return classObj;
        }
    };

    exports(plugName, handler);
}, rayui.jsAsync());
